//
// Created by gastonfeng on 2022/9/22.
//

#ifndef BOOTLOADER_STM32_DEVPROGFLASH_H
#define BOOTLOADER_STM32_DEVPROGFLASH_H


#include "hwboard.h"

class DevProgFlash : public mem_block {
public:
    DevProgFlash() {}

    DevProgFlash(uint32_t ba, uint32_t bb, uint32_t retain_size) {
        this->retain_size = retain_size;
        adr[0] = ba;
        adr[1] = bb;
    }

    void begin(const char *, int) override {
        //
    }

    void Remove(int i) override {
        board.progFlash.erasePage(adr[i], retain_size / 2048);
    }

    void Write(unsigned char i, unsigned int i2, void *pVoid, unsigned int len) override {
        board.progFlash.writeBytes(adr[i] + i2, pVoid, len);
    }

     int Read(u8 block, unsigned int i, unsigned int i1, void *pVoid) override {
        memcpy(pVoid, (const void *) (adr[block] + i), i1);
        return i1;
    }

    int Shutdown() override {
        return 0;
    }

    int begin_read(byte *name, byte name_sz, uint32_t start_address, uint32_t data_len) {
        return 0;
    }

#ifndef PLC

    int begin(byte *buf, byte sz, uint32_t start, uint32_t len) override {
        logger.debug("DevProgFlash::begin form 0x%x ,size=%d", start, sz);
        board.progFlash.erasePage(start, sz);
        a_size = *(uint32_t *) &buf[8];
        pos = 0;
        _start = start;
        return 256;
    }

    int Write(byte *buf, int len) {
        if (pos + len > a_size) {
            logger.error("size error ,size=%d,pos=%d,len=%d", a_size, pos, len);
        }
        board.progFlash.writeBytes(_start + pos, (const char *) buf, len);
        pos += len;
        return 0;
    }

#endif

    const char *name() override { return "QSPI"; }

private:
    uint32_t adr[2]{};
    uint32_t retain_size;
    uint32_t pos{}, a_size{};
    uint32_t _start{};
};


#endif //BOOTLOADER_STM32_DEVPROGFLASH_H
